package util;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.tapestry.json.JSONArray;
import org.apache.tapestry.json.JSONObject;


public class List2JSON<T> {

  /**
   * To JSON String
   * 
   * @param page
   *        当前页
   * @param count
   *        总数量
   * @param total
   *        总页数
   * @param datas
   *        数据集合
   * @param hostCellName
   *        主键列名
   * @param showCellNames
   *        显示列数组
   * @return
   * @throws Exception
   */
  public String toJSONString(int page, long count, int total, List<T> datas, String hostCellName, String[] showCellNames)
      throws Exception {
    return toJSON(page, count, total, datas, hostCellName, showCellNames).toString();
  }

  /**
   * To JSON
   * 
   * @param page
   *        当前页
   * @param count
   *        总数量
   * @param total
   *        总页数
   * @param datas
   *        数据集合
   * @param hostCellName
   *        主键列名
   * @param showCellNames
   *        显示列数组
   * @return
   * @throws Exception
   */
  @SuppressWarnings("unchecked")
  public JSONObject toJSON(int page, long count, int total, List<T> datas, String hostCellName, String[] showCellNames)
      throws Exception {
    JSONObject json = new JSONObject();
    json.put("page", page);
    json.put("records", count);
    json.put("total", total);
    JSONArray rows = new JSONArray();
    for (T t : datas) {
      JSONObject row = new JSONObject();
      JSONArray cell = new JSONArray();
      Map<String, Object> params = new HashMap<String, Object>();
      if (t instanceof Map) {
        params = (Map<String, Object>) t;
      } else {
        Util.convertParams(t, params);
      }
      row.put("id", params.get(hostCellName));
      for (String fieldName : showCellNames) {
        cell.put(params.get(fieldName));
      }
      row.put("cell", cell);
      rows.put(row);
    }
    json.put("rows", rows);
    return json;
  }

  /**
   * 
   * listToJson(这里用一句话描述这个方法的作用) (这里描述这个方法适用条件 – 可选)
   * 
   * @param datas
   * @param hostCellName
   * @param showCellNames
   * @return
   * @throws Exception
   *         JSONObject
   * @exception
   * @since 1.0.0
   */
  public JSONObject listToJson(List<T> datas, String hostCellName, String[] showCellNames) throws Exception {
    JSONObject json = new JSONObject();
    JSONArray rows = new JSONArray();
    for (T t : datas) {
      JSONObject row = new JSONObject();
      JSONArray cell = new JSONArray();
      Map<String, Object> params = new HashMap<String, Object>();
      Util.convertParams(t, params);
      row.put("id", params.get(hostCellName));
      for (String fieldName : showCellNames) {
        cell.put(params.get(fieldName));
      }
      row.put("cell", cell);
      rows.put(row);
    }
    json.put("rows", rows);
    return json;
  }

  /**
   * 把对象数据转成JSON数组
   * 
   * @param object
   * @param fieldNames
   * @return JSONArray
   * @throws Exception
   * @exception
   * @since 1.0.0
   */
  public JSONArray projectToJson(T object, String[] fieldNames) throws Exception {
    JSONArray datas = new JSONArray();
    if (object == null || fieldNames == null || fieldNames.length == 0) {
      return datas;
    }
    Map<String, Object> params = new HashMap<String, Object>();
    Util.convertParams(object, params);
    for (String fieldName : fieldNames) {
      datas.put(params.get(fieldName));
    }
    return datas;
  }

  /**
   * 把对象集合数据转成JSON二维数组
   * 
   * @param objects
   * @param fieldNames
   * @return JSONArray
   * @throws Exception
   * @exception
   * @since 1.0.0
   */
  public JSONArray listToJson(List<T> objects, String[] fieldNames) throws Exception {
    JSONArray datas = new JSONArray();
    if (objects == null || objects.isEmpty() || fieldNames == null || fieldNames.length == 0) {
      return datas;
    }
    for (T object : objects) {
      datas.put(projectToJson(object, fieldNames));
    }
    return datas;
  }

  /**
   * 获取字段值
   * 
   * @param t
   *        数据对象
   * @param fieldName
   *        字段名
   * @return
   * @throws Exception
   */
  @SuppressWarnings("unused")
private Object getFieldValue(T t, Class<?> c, String fieldName) throws Exception {
    if (t.getClass().getSuperclass() != null) {
      try {
        return getFieldValue(t, t.getClass().getSuperclass(), fieldName);
      } catch (NoSuchFieldException e) {
        getCurrenClassFieldValue(t, t.getClass(), fieldName);
      }
    }
    return getCurrenClassFieldValue(t, t.getClass(), fieldName);
  }

  private Object getCurrenClassFieldValue(Object t, Class<?> c, String fieldName) throws NoSuchFieldException,
      IllegalAccessException {
    Field f = c.getDeclaredField(fieldName);
    f.setAccessible(true);
    return f.get(t);
  }

  @SuppressWarnings("unused")
private static void getFieldValue(Object source, Map<String, Object> params, Class<?> c) {
    Class<?> s = c.getSuperclass();
    if (s != null) {
      if (s.equals(Object.class) == false) {
        getFieldValue(source, params, s);
      }
    }
    for (Field field : c.getDeclaredFields()) {
      field.setAccessible(true);
      Object fieldval = null;
      try {
        fieldval = field.get(source);
      } catch (IllegalArgumentException e) {
        LoggerUtils.errorInfo(e.getMessage(), e);
      } catch (IllegalAccessException e) {
        LoggerUtils.errorInfo(e.getMessage(), e);
      }
      if (fieldval != null && "serialVersionUID".equals(field.getName()) == false
          && "this$0".equals(field.getName()) == false) {
        params.put(field.getName(), fieldval);
      }
    }
  }

}
